﻿using Common.Entitys;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using ModuleDefinition = Common.Entitys.ModuleDefinition;

namespace Common.Utils
{
    /// <summary>
    /// 导入器相关
    /// </summary>
    public class ImportDefinitionHelp
    {
        #region 单例
        private static ImportDefinitionHelp m_Instance = new ImportDefinitionHelp();

        public static ImportDefinitionHelp Instance
        {
            get => m_Instance;
        }
        #endregion

        #region 字段

        //其中AllowRecomposition=true参数就表示运行在有新的部件被装配成功后进行部件集的重组.
        [ImportMany(AllowRecomposition = true)]
        public IEnumerable<IModuleDefinitionImporter> ModuleDefinitionImporters { get; set; }

        public Dictionary<(string, string), ModuleDefinition> DictIDDefinitions = new Dictionary<(string, string), ModuleDefinition>();

        //public Dictionary<string, ModuleDefinition> DictIDDefinitions = new Dictionary<string, ModuleDefinition>();
        #endregion

        private bool m_HaveInit = false;

        private ImportDefinitionHelp()
        {


        }

        public void Init(string path)
        {
            if (m_HaveInit)
            {
                return;
            }
            if (!Directory.Exists(path))
            {
                return;
            }
            DirectoryCatalog catalog = new DirectoryCatalog(path);
            CompositionContainer container = new CompositionContainer(catalog);
            container.ComposeParts(this);
            foreach (IModuleDefinitionImporter moduleDefinitionImporter in ModuleDefinitionImporters)
            {
                foreach (ModuleDefinition moduleDefinition in moduleDefinitionImporter.GetModuleDefinitions())
                {
                    DictIDDefinitions.TryAdd((moduleDefinition.Guid, moduleDefinition.VersionNumber), moduleDefinition);
                }
            }
            m_HaveInit = true;
        }


        /// <summary>
        /// 获取类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="version">版本号</param>
        /// <returns></returns>
        public T GetT<T>(string version) where T : class
        {
            string s = typeof(T).GUID.ToString("N");
            bool haveValue = DictIDDefinitions.TryGetValue((s, version), out ModuleDefinition moduleDefinition);
            if (haveValue)
            {
                if (moduleDefinition.IsUseInstance)
                {
                    // 获取类型
                    Type type = moduleDefinition.ModelViewType;

                    // 获取静态字段
                    var fieldInfo = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
                    if (fieldInfo != null)
                    {
                        return fieldInfo.GetValue(null) as T;
                    }
                }

                return Activator.CreateInstance(moduleDefinition.ModelViewType) as T;

            }
            else
            {
                return Activator.CreateInstance<T>();
            }
        }

        /// <summary>
        /// 获取类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="version">版本号</param>
        /// <returns></returns>
        public T GetT<T>(string version, string guid) where T : class
        {
            bool haveValue = DictIDDefinitions.TryGetValue((guid, version), out ModuleDefinition moduleDefinition);
            if (haveValue)
            {
                return Activator.CreateInstance(moduleDefinition.ModelViewType) as T;
            }
            else
            {
                return Activator.CreateInstance<T>();
            }
        }

    }
}
